﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace InfFront.InfoViews.Base
{
    public abstract class BaseInfoViewEntity: INotifyPropertyChanged, INotifyPropertyChanging
    {
        #region Private Variables
        private IVisualSettingsAccessor visualSettings = null;
        private string name;
        #endregion

        #region Constrution/Initialization

        protected BaseInfoViewEntity(string name, IVisualSettingsAccessor visualSettings)
        {
            this.name = name;
            this.visualSettings = visualSettings;
        }

        protected BaseInfoViewEntity(string name, BaseInfoViewEntity parent)
        {
            this.name = name;
            this.visualSettings = parent.VisualSettings.OpenChildSettings(name);
        }

        #endregion Constrution/Initialization

        #region Public Members

        public string Name 
        {
            get { return name; }
        }

        public IVisualSettingsAccessor VisualSettings
        {
            get { return visualSettings; }
        }

        #endregion Public Members

        #region Property Changing Notification

        protected void SetPropertyAndFire<T>(string propertyName, T newValue, ref T variable)
        {
            if ((newValue == null) != (variable == null))
                return;
            else if (newValue != null && !newValue.Equals(variable))
            {
                FirePropertyChanging(propertyName);
                variable = newValue;
                FirePropertyChanged(propertyName);
            }
        }

        protected void FirePropertyChanging(string propertyName)
        {
            PropertyChangingEventHandler handler = PropertyChanging;
            if (handler != null)
            {
                var args = new PropertyChangingEventArgs(propertyName);
                handler(this, args);
            }
        }

        protected void FirePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                var args = new PropertyChangedEventArgs(propertyName);
                handler(this, args);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public event PropertyChangingEventHandler PropertyChanging;

        #endregion Property Changing Notification
    }

    public interface IVisualSettingsManager
    {
        object AppGlobals { get; }
    }

    public interface IVisualSettingsAccessor : INotifyPropertyChanged
    {
        IVisualSettingsAccessor OpenChildSettings(string childName);

        object GetValue(string propName);
        void SetValue(string propName, object value);

        bool IsFrozen { get; set; }

        IVisualSettingsManager Manager { get; }
    }

    public class VisualSettingsFreezeState : IDisposable
    {
        IVisualSettingsAccessor entry = null;
        bool prevState;
        public VisualSettingsFreezeState(IVisualSettingsAccessor entry)
        {
            this.entry = entry;
            this.prevState = entry.IsFrozen;
            entry.IsFrozen = true;
        }

        #region IDisposable Members

        public void Dispose()
        {
            entry.IsFrozen = prevState;
            entry = null;
        }

        #endregion
    }

}
